package com.moon.game.server;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import org.apache.log4j.Logger;
import org.dom4j.Element;
import org.jboss.netty.bootstrap.ConnectionlessBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.FixedReceiveBufferSizePredictorFactory;
import org.jboss.netty.channel.socket.DatagramChannelFactory;
import org.jboss.netty.channel.socket.nio.NioDatagramChannelFactory;
import org.jboss.netty.handler.codec.protobuf.ProtobufDecoder;
import org.jboss.netty.handler.codec.protobuf.ProtobufEncoder;
import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;

import com.moon.game.clazz.PBMessageProto.PBMessage;
import com.moon.game.config.GlobalConfig;
import com.moon.game.util.ProfileConfig;


public class ProfileServer {
	private static int serverId;
	private static final Logger log = Logger.getLogger(ProfileServer.class);
	private static final String PROFILE_CONFIG_FILE = "mongo_config.xml";
	private static final String CONFIG_FILE = "config.xml";
	private static void initProfileConfig() {
		try {
			ProfileConfig.init(PROFILE_CONFIG_FILE);
		} catch (Exception e) {
			log.error("配置文件加载失败" + e.getMessage(),e);
		}
	}
	
	private static void initConfig() throws Exception {
		GlobalConfig.init(CONFIG_FILE);
	}
	
	private static class ProtoBufPipelineFactory implements ChannelPipelineFactory {
		public ChannelPipeline getPipeline() throws Exception {
			ChannelPipeline pipeline = Channels.pipeline();
			pipeline.addLast("frameDecoder", new ProtobufVarint32FrameDecoder());
			pipeline.addLast("protobufDecoder", new ProtobufDecoder(PBMessage.getDefaultInstance()));
			pipeline.addLast("frameEncoder", new ProtobufVarint32LengthFieldPrepender());
			pipeline.addLast("protobufEncoder", new ProtobufEncoder());
			pipeline.addLast("handler", new ProfileHandler());
			return pipeline;
		}
	}
	
	private static void startProfileServer() throws IOException {
	    DatagramChannelFactory factory = new NioDatagramChannelFactory(Executors.newCachedThreadPool());
	    ConnectionlessBootstrap bootstrap = new ConnectionlessBootstrap(factory);
	    bootstrap.setPipelineFactory(new ProtoBufPipelineFactory());
	    bootstrap.setOption("receiveBufferSizePredictorFactory", new FixedReceiveBufferSizePredictorFactory(2048));
	    Element element = GlobalConfig.getProfileServer(serverId);
		String host = element.attributeValue("bindip");
		int port = Integer.parseInt(element.attributeValue("bindport"));
		bootstrap.bind(new InetSocketAddress(host, port));
		log.info("start Profile Server,host:" + host + ",port:" + port);
	}
	
	public static void main(String[] args) {
		long start = System.currentTimeMillis();
		if (args.length < 1) {
			log.error("please set server id!");
			System.exit(0);
		}
		try {
			serverId = Integer.parseInt(args[0]);
			log.info("start profileserver: " + serverId);
			// 初始化mongo数据库配置
			initProfileConfig();
			// 初始化服务配置
			initConfig();
			// 启动Server
			startProfileServer();
			// 启动逻辑处理
			ProfileThread.init();
			ProfileThread.inst.start();
		} catch (Exception e) {
			log.error("profile server start error.", e);
			System.exit(0);
		}
		long end = System.currentTimeMillis();
		log.info("start profile server use:" + (end - start) + "ms");
	}
}
